package com.uselaw.api.security;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;

import java.util.List;

/**
 * ConsumerJdbcDaoImpl
 *
 * @ClassName: ConsumerJdbcDaoImpl
 * @Description:ConsumerJdbcDaoImpl
 * @author: maxf
 * @date: 2017年12月21日 下午6:17:12
 */
public class ConsumerJdbcDaoImpl extends JdbcDaoImpl {
    public ConsumerJdbcDaoImpl(JdbcTemplate jdbcTemplate, String usersByUsernameQueryString,
                               String authoritiesByUsernameQueryString) {
        this.setJdbcTemplate(jdbcTemplate);
        this.setUsersByUsernameQuery(usersByUsernameQueryString);
        this.setAuthoritiesByUsernameQuery(authoritiesByUsernameQueryString);
    }

    public ConsumerJdbcDaoImpl(JdbcTemplate jdbcTemplate) {
        this.setJdbcTemplate(jdbcTemplate);
    }

    /**
     * Executes the SQL <tt>usersByUsernameQuery</tt> and returns a list of
     * UserDetails objects. There should normally only be one matching user.
     */
    @Override
    protected List<UserDetails> loadUsersByUsername(String username) {
        return getJdbcTemplate().query(super.getUsersByUsernameQuery(), new String[]{username},
                (rs, rowNum) -> {
                    String username1 = rs.getString(1);
                    String password = rs.getString(2);
                    String id = rs.getString(3);
                    boolean enabled = rs.getBoolean(4);
                    boolean accountExpired = rs.getBoolean(5);
                    boolean accountLocked = rs.getBoolean(6);
                    return new ConsumerUser(username1, password, enabled, accountExpired, true, accountLocked,
                            AuthorityUtils.NO_AUTHORITIES, id);
                });
    }

    /**
     * Can be overridden to customize the creation of the final UserDetailsObject
     * which is returned by the <tt>loadUserByUsername</tt> method.
     *
     * @param username            the name originally passed to loadUserByUsername
     * @param userFromUserQuery   the object returned from the execution of the
     * @param combinedAuthorities the combined array of authorities from all the authority loading
     *                            queries.
     * @return the final UserDetails which should be used in the system.
     */
    @Override
    protected UserDetails createUserDetails(String username, UserDetails userFromUserQuery,
                                            List<GrantedAuthority> combinedAuthorities) {
        if (!(userFromUserQuery instanceof ConsumerUser)) {
            return super.createUserDetails(username, userFromUserQuery, combinedAuthorities);
        }

        ConsumerUser consumerUser = (ConsumerUser) userFromUserQuery;
        String returnUsername = consumerUser.getUsername();

        if (!super.isUsernameBasedPrimaryKey()) {
            returnUsername = username;
        }

        return new ConsumerUser(returnUsername, consumerUser.getPassword(), consumerUser.isEnabled(),
                consumerUser.isAccountNonExpired(), consumerUser.isCredentialsNonExpired(),
                consumerUser.isAccountNonLocked(), combinedAuthorities, consumerUser.getId());

    }

    /**
     * Allows subclasses to add their own granted authorities to the list to be
     * returned in the <tt>UserDetails</tt>.
     *
     * @param username    the username, for use by finder methods
     * @param authorities the current granted authorities, as populated from the
     *                    <code>authoritiesByUsername</code> mapping
     */
    @Override
    protected void addCustomAuthorities(String username, List<GrantedAuthority> authorities) {
        // 动态添加用户属性
    }
}
